/*
*  Copyright 2019-2020 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package me.zhengjie.business.service.impl;

import lombok.extern.slf4j.Slf4j;
import me.zhengjie.business.domain.Sbgs;
import me.zhengjie.business.domain.vo.HljgDspVo;
import me.zhengjie.business.domain.vo.KB03;
import me.zhengjie.business.domain.vo.KB22;
import me.zhengjie.business.service.dto.ZhsqDto;
import me.zhengjie.modules.system.domain.Dept;
import me.zhengjie.modules.system.domain.Role;
import me.zhengjie.modules.system.domain.User;
import me.zhengjie.modules.system.repository.DeptRepository;
import me.zhengjie.modules.system.repository.UserRepository;
import me.zhengjie.modules.system.service.DeptService;
import me.zhengjie.pay.domain.PaidQueryCriteria;
import me.zhengjie.utils.*;
import lombok.RequiredArgsConstructor;
import me.zhengjie.business.repository.SbgsRepository;
import me.zhengjie.business.service.SbgsService;
import me.zhengjie.business.service.dto.SbgsDto;
import me.zhengjie.business.service.dto.SbgsQueryCriteria;
import me.zhengjie.business.service.mapstruct.SbgsMapper;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.hutool.core.util.IdUtil;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.*;
import java.io.IOException;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;

/**
* @website https://el-admin.vip
* @description 服务实现
* @author xiahongbo
* @date 2022-04-13
**/
@Slf4j
@Service
@RequiredArgsConstructor
public class SbgsServiceImpl implements SbgsService {

    private final PasswordEncoder passwordEncoder;
    private final UserRepository userRepository;
    private final DeptRepository deptRepository;
    private final SbgsRepository sbgsRepository;
    private final SbgsMapper sbgsMapper;
    private final RedisUtils redisUtils;

    @Override
    public Map<String,Object> queryAll(SbgsQueryCriteria criteria, Pageable pageable){
        log.info("SbgsServiceImpl queryAll criteria : {}", criteria);
        log.info("SbgsServiceImpl queryAll pageable : {}", pageable);
        Page<Sbgs> page = sbgsRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        Map<String,Object> m = PageUtil.toPage(page.map(sbgsMapper::toDto));
        log.info("SbgsServiceImpl queryAll m : {}", m);
        return m;
    }

    @Override
    public List<SbgsDto> queryAll(SbgsQueryCriteria criteria){
        return sbgsMapper.toDto(sbgsRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    @Transactional
    public SbgsDto findById(String bisGsglId) {
        Sbgs sbgs = sbgsRepository.findById(bisGsglId).orElseGet(Sbgs::new);
        ValidationUtil.isNull(sbgs.getBisGsglId(),"Sbgs","bisGsglId",bisGsglId);
        return sbgsMapper.toDto(sbgs);
    }

    @Override
    public SbgsDto findByBisGsglUserId(Long bisSbgsUserId) {
        return sbgsMapper.toDto(sbgsRepository.findByBisGsglUserId(bisSbgsUserId));
    }

    @Override
    public Sbgs findByBisGsglUserId1(Long bisSbgsUserId) {
        return sbgsRepository.findByBisGsglUserId(bisSbgsUserId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SbgsDto create(Sbgs resources) {

        // 新增商保公司，需要模拟用户插入
        User user = new User();
        user.setUsername(resources.getBisGsglYljgdm());
        user.setPassword(passwordEncoder.encode(DefaultUtil.PASSWORD));
        user.setNickName(resources.getBisGsglQymc());
        user.setPhone(resources.getBisGsglLxrdh());
        user.setEnabled(true);
        user.setIsAdmin(false);

        // 新增用户，模拟商保公司部门
        Dept dept = new Dept();
        dept.setPid(DefaultUtil.DEPT_SB);
        dept.setName(resources.getBisGsglQymc());
        dept.setEnabled(true);
        dept.setDeptSort(999);
        Dept newDept = deptRepository.save(dept);

        dept.setSubCount(0);
        // 计算子节点数目
        int count = deptRepository.countByPid(DefaultUtil.DEPT_SB);
        deptRepository.updateSubCntById(count, DefaultUtil.DEPT_SB);
        user.setDept(newDept);

        List<User> users = userRepository.findByRoleDeptId(DefaultUtil.DEPT_SB);
        // 删除数据权限
        redisUtils.delByKeys(CacheKey.DATA_USER, users.stream().map(User::getId).collect(Collectors.toSet()));
        redisUtils.del(CacheKey.DEPT_ID + DefaultUtil.DEPT_SB);

        // 新增用户，模拟商保公司角色
        Set<Role> setRole = new HashSet<Role>();
        Role role = new Role();
        role.setId(DefaultUtil.ROLE_SB);
        setRole.add(role);
        user.setRoles(setRole);

        user = userRepository.save(user);

        // 新增商保公司
        resources.setBisGsglId(IdUtil.simpleUUID());
        resources.setBisGsglUserId(newDept.getId());
        return sbgsMapper.toDto(sbgsRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(Sbgs resources) {
        Sbgs sbgs = sbgsRepository.findById(resources.getBisGsglId()).orElseGet(Sbgs::new);
        ValidationUtil.isNull( sbgs.getBisGsglId(),"Sbgs","id",resources.getBisGsglId());
        sbgs.copy(resources);
        sbgsRepository.save(sbgs);
    }

    @Override
    public void deleteAll(String[] ids) {
        for (String bisSbgsId : ids) {
            sbgsRepository.deleteById(bisSbgsId);
        }
    }

    @Override
    public void download(List<SbgsDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (SbgsDto sbgs : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public void downloadKb03(List<KB03> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (KB03 project : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("统筹区", project.getAab034());
            map.put("服务机构编号", project.getAkb020());
            map.put("服务机构名称", project.getAkb021());
            map.put("费款所属期", project.getAae002());
            map.put("照护类型", "4".equals(project.getAae016()) ? "机构" : "居家");
            map.put("参保类型", project.getCjt100());
            map.put("住院人次", project.getAkb062());
            map.put("住院个人现金支出", project.getCkb152());
            map.put("住院帐户支出金额", project.getCkb151());
            map.put("住院公务员补助支出", project.getCkb153());
            map.put("统筹支付金额", project.getAkb068());
            map.put("救助金支出", project.getZkb060());
            map.put("特殊人员支付", project.getTsryzf());
            map.put("二级保健对象支付", project.getCkb156());
            map.put("住院高知支付", project.getCkb208());
            map.put("一级保健对象支付", project.getYjbjdx());
            map.put("住院费用", project.getAkb064());
            map.put("住院实际偿付总额", project.getCkb161());
            map.put("住院预留风险基金总额", project.getCkb169());
            map.put("拨付机构名称", project.getInsuName());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public List<KB03> queryKb03(PaidQueryCriteria criteria) {
        return sbgsRepository.queryKb03(criteria.getAkb020(), criteria.getAae002(), criteria.getInsuNo());
    }

    @Override
    public void downloadKb22(List<KB22> all, HttpServletResponse response) throws IOException {

        List<Map<String, Object>> list = new ArrayList<>();
        for (KB22 project : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("服务机构编号", project.getAkb020());
            map.put("结算期", project.getAae002());
            map.put("照护类型", "1".equals(project.getAaa022()) ? "机构" : "居家");
            map.put("参保类型", "1".equals(project.getCjt100()) ? "居民" : "职工");
            map.put("姓名", project.getAac003());
            map.put("身份证", project.getAac002());
            map.put("入院日期", project.getAkc192());
            map.put("出院日期", project.getAkc194());
            map.put("费用总额", project.getAkc264());
            map.put("统筹报销", project.getAkc260());
            map.put("账户支付", project.getAkc255());
            map.put("个人现金", project.getAkc261());
            map.put("拨付金额", project.getAaa005());
            map.put("预留", project.getYl());
            map.put("当期拨付", project.getDqbo());
            map.put("养老机构录入照护数量", project.getZkc024());
            map.put("通过计算实际拨付照护数量", project.getAkc268());
            map.put("护理扣减数量", project.getKjsl());
            map.put("护理扣减金额", project.getHlkjje());
            map.put("耗材扣减金额", project.getHckjje());
            map.put("本次理论照护数量", project.getAkc265());
            map.put("扣减天数", project.getCkc283());
            map.put("ADL总分", project.getAdlTotal());
            map.put("异常备注", project.getAae013());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public List<KB22> queryKb22(PaidQueryCriteria criteria) {
        return sbgsRepository.queryKb22(criteria.getAkb020(), criteria.getAae002(), criteria.getCjt100(), criteria.getAaa022(), criteria.getInsuNo(), criteria.getAab034());
    }

    @Override
    public Map<String, Object> queryHljgCntVoPageList(String zhlb, String sbId, String jgxx, List<String> zt, Pageable pageable) {
        Page<HljgDspVo> page = sbgsRepository.queryHljgCntVoPageList(zhlb, sbId, jgxx, zt, pageable);
        return PageUtil.toPage(page);
    }
}